
import { _decorator, Component, Node, systemEvent, SystemEventType, EventKeyboard, macro, RigidBody, Vec3, misc, Collider, EventMouse, PhysicsSystem, Camera, game } from 'cc';
const { ccclass, property } = _decorator;

const Input: { [k: string]: any } = {}

@ccclass('Player')
export class Player extends Component {

    // 头部组件
    @property(Node)
    private headNode: Node = null!;

    // 主摄像头。移动跟随的第一视角
    @property(Camera)
    private mainC: Camera = null!;

    private canJmp = true;
    private isMouseDown = false;

    // [1]
    // dummy = '';

    // [2]
    // @property
    // serializableDummy = 0;

    start() {
        // [3]

        // 键盘事件
        systemEvent.on(SystemEventType.KEY_DOWN, (e: EventKeyboard) => {
            Input[e.keyCode] = true
        }, this);
        systemEvent.on(SystemEventType.KEY_UP, (e: EventKeyboard) => {
            Input[e.keyCode] = false
        }, this);

        // 鼠标事件
        // 鼠标按下
        systemEvent.on(SystemEventType.MOUSE_DOWN, (e: EventMouse) => {
            console.log("MOUSE_DOWN");

            this.cursor("move");
            this.isMouseDown = true;
        }, this);
        // 鼠标释放
        systemEvent.on(SystemEventType.MOUSE_UP, (e: EventMouse) => {
            console.log("MOUSE_UP");
            this.cursor("default");
            this.isMouseDown = false;

        }, this);
        // 鼠标控制视角
        systemEvent.on(SystemEventType.MOUSE_MOVE, (e: EventMouse) => {

            // 鼠标释放时
            if (!this.isMouseDown) {

                this.cursor("default");
                let touchPos = e.getLocation();
                let ray = this.mainC.screenPointToRay(touchPos.x, touchPos.y);

                if (PhysicsSystem.instance.raycastClosest(ray)) {
                    const res = PhysicsSystem.instance.raycastClosestResult;

                    const coll = res.collider;
                    console.log(coll.name);
                    if (coll.name.startsWith('Cube'))
                        this.cursor("hand");
                }
                return;
            }

            // 移速
            let angel_speed = 5;
            // console.log("MOUSE_MOVE");
            // 鼠标按下之后移动的距离
            let delta = e.getDelta();
            // 左移
            if (delta.x < 0) {
                let angle = this.node.eulerAngles;
                let angelY = angle.y + angel_speed;
                this.node.eulerAngles = new Vec3(angle.x, angelY, angle.z);
            }
            // 右移
            else if (delta.x > 0) {
                let angle = this.node.eulerAngles;
                let angelY = angle.y - angel_speed;
                this.node.eulerAngles = new Vec3(angle.x, angelY, angle.z);
            }
            // 前移
            if (delta.y > 0) {
                let angle = this.headNode.eulerAngles;
                let angelX = angle.x + angel_speed;
                if (angelX > 90) {
                    angelX = 90;
                }
                this.headNode.eulerAngles = new Vec3(angelX, angle.y, angle.z);
            }
            // 后移
            else if (delta.y < 0) {
                let angle = this.headNode.eulerAngles;
                let angelX = angle.x - angel_speed;
                if (angelX < -90) {
                    angelX = -90;
                }
                this.headNode.eulerAngles = new Vec3(angelX, angle.y, angle.z);
            }
        }, this);


        // 碰撞事件
        let coll = this.getComponent(Collider);
        // 碰撞到刚体之后允许跳跃
        coll?.on("onCollisionEnter", () => {
            this.canJmp = true;
        }, this)

        // 触屏事件
        systemEvent.on(SystemEventType.TOUCH_START, (t) => {
            console.log("touch")
            let touchPos = t.getLocation();
            let ray = this.mainC.screenPointToRay(touchPos.x, touchPos.y);

            if (PhysicsSystem.instance.raycastClosest(ray)) {
                const res = PhysicsSystem.instance.raycastClosestResult;

                const coll = res.collider;
                console.log(coll.name);
                if (coll.name.startsWith('Cube')) {
                    console.log("Cube");
                    // window.open("http://dfer.top")
                    let rb = coll.getComponent(RigidBody);
                    // 往上
                    rb?.applyForce(new Vec3(0, 1000, 0))
                }

            }


        }, this)

    }


    cursor(type: string) {
        game.canvas.style.cursor = type;
    }




    update(deltaTime: number) {
        // 移速
        let speed = 5;
        // 跳速
        let jump_speed = 5;
        // 转速
        let angel_speed = 2;

        let lv = new Vec3();
        // 获取当前的刚体
        let rb = this.node.getComponent(RigidBody);
        rb?.getLinearVelocity(lv);

        // 根据input值进行移动
        if (Input[macro.KEY.w]) {
            lv.z = -speed;
            lv.x = 0;
        } else if (Input[macro.KEY.s]) {
            lv.z = speed;
            lv.x = 0;

        } else if (Input[macro.KEY.a]) {
            lv.x = -speed;
            lv.z = 0;

        } else if (Input[macro.KEY.d]) {
            lv.x = speed;
            lv.z = 0;
        } else {
            lv = new Vec3(0, lv.y, 0,);
        }

        if (Input[macro.KEY.space] && this.canJmp) {
            lv.y = jump_speed;
            this.canJmp = false;
        }

        // 转身
        let angle = this.node.eulerAngles;
        if (Input[macro.KEY.q]) {
            this.node.setRotationFromEuler(new Vec3(angle.x, angle.y + angel_speed, angle.z))
        } else if (Input[macro.KEY.e]) {
            this.node.setRotationFromEuler(new Vec3(angle.x, angle.y - angel_speed, angle.z))
        }

        // 获取旋转之后的值
        Vec3.transformQuat(lv, lv, this.node.getRotation());

        // 生效
        rb?.setLinearVelocity(lv);




        // [4]
    }
}

/**
 * [1] Class member could be defined like this.
 * [2] Use `property` decorator if your want the member to be serializable.
 * [3] Your initialization goes here.
 * [4] Your update function goes here.
 *
 * Learn more about scripting: https://docs.cocos.com/creator/3.0/manual/en/scripting/
 * Learn more about CCClass: https://docs.cocos.com/creator/3.0/manual/en/scripting/ccclass.html
 * Learn more about life-cycle callbacks: https://docs.cocos.com/creator/3.0/manual/en/scripting/life-cycle-callbacks.html
 */
